package au.com.acpfg.misc.spectra.writer;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import org.knime.core.data.DataCell;
import org.knime.core.data.DataColumnSpec;
import org.knime.core.data.DataColumnSpecCreator;
import org.knime.core.data.DataRow;
import org.knime.core.data.DataTableSpec;
import org.knime.core.data.RowIterator;
import org.knime.core.data.RowKey;
import org.knime.core.data.def.DefaultRow;
import org.knime.core.data.def.DoubleCell;
import org.knime.core.data.def.IntCell;
import org.knime.core.data.def.StringCell;
import org.knime.core.node.BufferedDataContainer;
import org.knime.core.node.BufferedDataTable;
import org.knime.core.node.CanceledExecutionException;
import org.knime.core.node.defaultnodesettings.SettingsModelBoolean;
import org.knime.core.node.defaultnodesettings.SettingsModelIntegerBounded;
import org.knime.core.node.defaultnodesettings.SettingsModelString;
import org.knime.core.node.ExecutionContext;
import org.knime.core.node.ExecutionMonitor;
import org.knime.core.node.InvalidSettingsException;
import org.knime.core.node.NodeLogger;
import org.knime.core.node.NodeModel;
import org.knime.core.node.NodeSettingsRO;
import org.knime.core.node.NodeSettingsWO;
import au.com.acpfg.misc.spectra.MGFSpectraCell;
import au.com.acpfg.misc.spectra.SpectralDataInterface;
/**
* This is the model implementation of SpectraWriter.
* Writes a spectra column out to disk for processing with other Mass Spec. software. Supports MGF format but does not guarantee that all input data will be preserved in the created file.
*
* @author Andrew Cassin
*/
public class SpectraWriterNodeModel extends NodeModel {
// the logger instance
private static final NodeLogger logger = NodeLogger
.getLogger(SpectraWriterNodeModel.class);
/** the settings key which is used to retrieve and
store the settings (from the dialog or from a settings file)
(package visibility to be usable from the dialog). */
static final String CFGKEY_FILE = "output-file";
static final String CFGKEY_OVERWRITE = "overwrite";
static final String CFGKEY_FORMAT = "file-format";
static final String CFGKEY_COLUMN = "spectra";
private static final String DEFAULT_FILE = "c:/temp/spectra.mgf";
private static final boolean DEFAULT_OVERWRITE = false;
private static final String DEFAULT_FORMAT = "Mascot Generic Format";
private static final String DEFAULT_COLUMN = "Spectra";
// example value: the models count variable filled from the dialog
// and used in the models execution method. The default components of the
// dialog work with "SettingsModels".
private final SettingsModelString m_file = new SettingsModelString(CFGKEY_FILE, DEFAULT_FILE);
private final SettingsModelBoolean m_overwrite = new SettingsModelBoolean(CFGKEY_OVERWRITE, DEFAULT_OVERWRITE);
private final SettingsModelString m_format = new SettingsModelString(CFGKEY_FORMAT, DEFAULT_FORMAT);
private final SettingsModelString m_col = new SettingsModelString(CFGKEY_COLUMN, DEFAULT_COLUMN);
/**
* Constructor for the node model.
*/
protected SpectraWriterNodeModel() {
super(1, 0);
}
/**
* {@inheritDoc}
*/
@Override
protected BufferedDataTable[] execute(final BufferedDataTable[] inData,
final ExecutionContext exec) throws Exception {
int col_idx = inData[0].getDataTableSpec().findColumnIndex(m_col.getStringValue());
if (col_idx < 0) {
throw new Exception("Cannot find column: "+m_col.getStringValue()+"... bug?");
}
RowIterator it = inData[0].iterator();
int done = 0;
int todo = inData[0].getRowCount();
PrintWriter pw = new PrintWriter(new FileWriter(new File(m_file.getStringValue())));
while (it.hasNext()) {
DataRow r = it.next();
SpectralDataInterface sdi = (SpectralDataInterface) r.getCell(col_idx);
double[] mz = sdi.getMZ();
double[] intensity = sdi.getIntensity();
String title = sdi.getID();
int tc = sdi.getMSLevel();
// HACK TODO: get charge and pepmass via SpectraDataInterface?
String charge = "";
String pepmass= null;
if (sdi instanceof MGFSpectraCell) {
MGFSpectraCell mgf = (MGFSpectraCell) sdi;
charge = mgf.getCharge();
pepmass= mgf.getPepmass();
if (pepmass != null && pepmass.trim().length() == 0)
pepmass = null;
}
if (done % 100 == 0) {
exec.checkCanceled();
exec.setProgress(((double) done)/todo, "Processing spectra "+done);
}
// write the spectra to the output file
pw.println("BEGIN IONS");
pw.println("TITLE="+title);
pw.println("CHARGE="+charge);
if (pepmass != null)
pw.println("PEPMASS="+pepmass);
for (int i=0; i<mz.length; i++) {
pw.print(mz[i]);
pw.print(' ');
pw.println(intensity[i]);
}
pw.println("END IONS");
done++;
}
// close the file
pw.close();
logger.info("Wrote "+done+" spectra.");
// done!
return new BufferedDataTable[]{};
}
/**
* {@inheritDoc}
*/
@Override
protected void reset() {
}
/**
* {@inheritDoc}
*/
@Override
protected DataTableSpec[] configure(final DataTableSpec[] inSpecs)
throws InvalidSettingsException {
// TODO: check if user settings are available, fit to the incoming
// table structure, and the incoming types are feasible for the node
// to execute. If the node can execute in its current state return
// the spec of its output data table(s) (if you can, otherwise an array
// with null elements), or throw an exception with a useful user message
return new DataTableSpec[]{};
}
/**
* {@inheritDoc}
*/
@Override
protected void saveSettingsTo(final NodeSettingsWO settings) {
m_col.saveSettingsTo(settings);
m_file.saveSettingsTo(settings);
m_format.saveSettingsTo(settings);
m_overwrite.saveSettingsTo(settings);
}
/**
* {@inheritDoc}
*/
@Override
protected void loadValidatedSettingsFrom(final NodeSettingsRO settings)
throws InvalidSettingsException {
m_col.loadSettingsFrom(settings);
m_file.loadSettingsFrom(settings);
m_format.loadSettingsFrom(settings);
m_overwrite.loadSettingsFrom(settings);
}
/**
* {@inheritDoc}
*/
@Override
protected void validateSettings(final NodeSettingsRO settings)
throws InvalidSettingsException {
m_col.validateSettings(settings);
m_file.validateSettings(settings);
m_format.validateSettings(settings);
m_overwrite.validateSettings(settings);
}
/**
* {@inheritDoc}
*/
@Override
protected void loadInternals(final File internDir,
final ExecutionMonitor exec) throws IOException,
CanceledExecutionException {
}
/**
* {@inheritDoc}
*/
@Override
protected void saveInternals(final File internDir,
final ExecutionMonitor exec) throws IOException,
CanceledExecutionException {
}
}